home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / pine3.92 / pine / osdep / sunquota < prev    next >
Text File  |  1993-08-10  |  4KB  |  136 lines

  1. static char *device_name();
  2.  
  3. /*----------------------------------------------------------------------
  4.    Return space left in disk quota on file system which given path is in.
  5.  
  6.     Args: path - Path name of file or directory on file system of concern
  7.           over - pointer to flag that is set if the user is over quota
  8.  
  9.  Returns: If *over = 0, the number of bytes free in disk quota as per
  10.           the soft limit.
  11.       If *over = 1, the number of bytes *over* quota.
  12.           -1 is returned on an error looking up quota
  13.            0 is returned if there is no quota
  14.  
  15. BUG:  If there's more than 2.1Gb free this function will break
  16.   ----*/
  17. long
  18. disk_quota(path, over)
  19.     char *path;
  20.     int  *over;
  21. {
  22.     static int   no_quota = 0;
  23.     struct stat  statx;
  24.     struct dqblk quotax;
  25.     long         q;
  26.     char        *dname;
  27.  
  28.     if(no_quota)
  29.       return(0L); /* If no quota the first time, then none the second. */
  30.  
  31.     dprint(5, (debugfile, "quota_check path: %s\n", path));
  32.     if(stat(path, &statx) < 0) {
  33.         return(-1L);
  34.     }
  35.  
  36.     *over = 0;
  37.     errno = 0;
  38.  
  39.     dname = device_name(statx.st_dev);
  40.     if(dname == NULL)
  41.       return(-1L);
  42.  
  43.     dprint(7, (debugfile, "Quota check: UID:%d  device: %s\n", 
  44.            getuid(), dname));
  45.     if(quotactl(Q_GETQUOTA, dname, getuid(), (char *)"ax) < 0) {
  46.         dprint(5, (debugfile, "Quota failed : %s\n",
  47.                    error_description(errno)));
  48.         return(-1L); /* Something went wrong */
  49.     }
  50.  
  51.     dprint(5,(debugfile,"Quota: bsoftlimit:%d  bhardlimit:%d  curblock:%d\n",
  52.           quotax.dqb_bsoftlimit, quotax.dqb_bhardlimit, quotax.dqb_curblocks));
  53.  
  54.     if(quotax.dqb_bsoftlimit == -1)
  55.       return(-1L);
  56.  
  57.     q = (quotax.dqb_bsoftlimit - quotax.dqb_curblocks) * 512;    
  58.  
  59.     if(q < 0) {
  60.         q = -q;
  61.         *over = 1;
  62.     }
  63.     dprint(5, (debugfile, "disk_quota returning :%d,  over:%d\n", q, *over));
  64.     return(q);
  65. }
  66.  
  67.  
  68. /*----------------------------------------------------------------------
  69.  *        devNumToName
  70.  *
  71.  *    This routine is here so that ex can get a device name to check
  72.  *    disk quotas.  One might wonder, why not use getmntent(), rather
  73.  *    than read /etc/mtab in this crude way?  The problem with getmntent
  74.  *    is that it uses stdio, and ex/vi pointedly doesn't.
  75.  ----*/
  76. static  char
  77. *device_name(st_devArg)
  78.     dev_t st_devArg;
  79. {
  80. #ifndef MTABNAME
  81. #define MTABNAME "/etc/mtab"
  82. #endif
  83.     char *mtab;
  84.     static char devName[48];
  85.     static char *answer = (char *) 0;
  86.     struct stat devStat;
  87.     static dev_t st_dev;
  88.     int nb, cur, bol;
  89.     char c;
  90.     int dname;
  91.  
  92.     if (st_devArg == st_dev)
  93.       return answer;
  94.  
  95.     mtab = read_file(MTABNAME);
  96.     if(mtab == NULL)
  97.       return((char *)NULL);
  98.  
  99.     /* Initialize save data. */
  100.     st_dev = st_devArg;
  101.     answer = (char *) 0;
  102.     nb = strlen(mtab);
  103.  
  104.     for (cur=bol=0, dname=1; cur < nb; ++cur) {
  105.  
  106.     if (dname && (mtab[cur] <= ' ')) {
  107.     /*    Space, tab or other such character has been found,
  108.         presumably marking the end of the device name string. */
  109.     
  110.         dname = 0;
  111.         c = mtab[cur];    /* Save current character. */
  112.         mtab[cur] = 0;    /* C zero-terminated string. */
  113.  
  114.         /*    Get device number, via stat().  If it's the right
  115.         number, copy the string and return its address. */
  116.         if (stat (&mtab[bol], &devStat) == 0) {
  117.         if (devStat.st_rdev == st_dev) {
  118.             if ((cur - bol + 1) < sizeof (devName)) {
  119.             strcpy (devName, &mtab[bol]);
  120.                         answer = &devName[0];
  121.             return(answer);
  122.             }
  123.         }
  124.         }
  125.         mtab[cur] = c;
  126.     }
  127.     if (mtab[cur] == '\n') {
  128.         dname = 1;
  129.         bol = cur + 1;
  130.     }
  131.     }
  132.     answer = NULL;
  133.  
  134.     return(answer);
  135. }
  136.